﻿/**
 * Copyright 2018 北京伯睿科技有限公司.
 * All Rights Reserved.
 *  
 *
 * @TransferOfAxes
 * @TransferOfAxes 坐标系转换类
 *
 * @Author 牛瑞杰
 * @Date 2019年9月5日
 * @Version 1.0
 */

using UnityEngine;
using Framework.Mathd;
using Framework.Common;
using Framework.Math;
using System.Collections.Generic;

namespace BridgeShips {
    public class TransferOfAxes : Singleton<TransferOfAxes> {
        public Transform m_BottomRightPoint; //下桥点
        public Transform m_TopRightPoint;//Unity中左上点  （Z轴正方向和X轴负方向之间）
        public Vector3 m_TopLeftResultPoint;//Unity中左上点  （Z轴正方向和X轴负方向之间）
        public Vector3 m_BottomRightResultPoint;//Unity中右下点  （X正方向和Z轴的负方向之间）

        private Vector2d m_BottomRightSai;//地图中对应的左上经纬度点  
        private Vector2d m_TopRightSai;//地图中对应的右下经纬度点  
        private Vector2d m_CenterOfBottomTopRightFixSai;//地图中对应的上桥点和下桥点的中心点  
        private Vector2d m_BottomRightFixResultSai;//最终使用的
        private Vector2d m_TopLeftFixResultSai;

        private double m_riverAngle = 0.0;//上桥点与下桥点 连线与正北方向的夹角（0~360） 

        // public GameObject m_StandardCoordinate; //
        //public Quaternion m_ConverQuat;

        public Vector3 m_ReiverCenterPoint = Vector3.zero;//Unity中左上点  （Z轴正方向和X轴负方向之间）
        public Vector3 m_ReiverCenterOffectPoint = Vector3.zero;//Unity中左上点  （Z轴正方向和X轴负方向之间）


        private double m_offsetLati_z, m_offsetLon_x, m_ZWoffsetPoint, m_XWoffsetPoint;

        private double m_converX, m_converZ;

        private bool m_Active = true;

        private float m_RiverWidth = 1000.0f;

        private CaculateLonAndLatiData m_caculLonLatData = null;

        GameObject willReatchPointObj = new GameObject();


        //上岸点
        //118.553342,31.862717
        //下岸水点
        //118.555559,31.862327

        public void InitBridgePosition() {

            //*  采集点 *//
            m_BottomRightSai = new Vector2d(118.5553802, 31.862087); // 上桥点  

             m_TopRightSai = new Vector2d(118.553342, 31.862387);   // 下桥点

            Vector2d firstPoint = new Vector2d(118.555080, 31.862087);   //计算点
            /*
             *                                 /   /                f0                                 
             *                                /  f1  (m_TopRightPoint)m_TopRightSai   
             *                               f0  /     
             *       (f1)                   /   / 
             *       m_BottomRightPoint    /   /    
             */

            m_BottomRightPoint = TerrainsMove.Instance.GetBridgePoint1(); // 上桥点  
            m_TopRightPoint = TerrainsMove.Instance.GetBridgePoint2();    // 下桥点

            m_RiverWidth = (float)Haversine.Distance(m_BottomRightSai.y, m_BottomRightSai.x, m_TopRightSai.y, m_TopRightSai.x) * 1000.0f;
            m_TopRightPoint.position = new Vector3(m_BottomRightPoint.position.x + m_RiverWidth, 7.0f, m_TopRightPoint.position.z);
            //TerrainsMove.Instance.SetBridgePoint2(briPoint2);
           // Debug.LogError("m_RiverWidth = " + m_RiverWidth);

            // AB连线与正北方向的夹角（0~360） 
            WorldLatLngAngle A = new WorldLatLngAngle(m_BottomRightSai.x, m_BottomRightSai.y);
            WorldLatLngAngle B = new WorldLatLngAngle(m_TopRightSai.x, m_TopRightSai.y);
            m_riverAngle = 360.0f-WorldLatLngAngle.getAngle(A, B) + 90.0f;
           // Debug.LogError("m_riverAngle = " + m_riverAngle);
            //计算经纬度 上桥点下桥点中心点
            m_CenterOfBottomTopRightFixSai = GetCenterCoordinate(m_BottomRightSai, m_TopRightSai);

           double maxLatitude, minLatitude, maxLongitude, minLongitude;

            TerrainsMove.Instance.CaculateRectRegionPointResult();
            m_BottomRightResultPoint = TerrainsMove.Instance.GetBridgePointBottleRightResult();
            m_TopLeftResultPoint = TerrainsMove.Instance.GetBridgePointTopLeftResult();
            float edgeLength = TerrainsMove.Instance.GetRegionEdgeLenght() / 1000.0f;
            Haversine.GetRectRange(m_CenterOfBottomTopRightFixSai.y, m_CenterOfBottomTopRightFixSai.x,
                edgeLength, out maxLatitude, out minLatitude, out maxLongitude, out minLongitude);

            m_ReiverCenterPoint = (m_BottomRightPoint.position + m_TopRightPoint.position) * 0.5f;
            m_ReiverCenterPoint.y = 7.0f;

            //计算最终的矩形的左上角，右下角采集 经纬度坐标点
            m_BottomRightFixResultSai = new Vector2d(maxLongitude, minLatitude);
            m_TopLeftFixResultSai = new Vector2d(minLongitude, maxLatitude);     //ShipsDictionary.Instance.GetOriginalPoint();

            if ( m_BottomRightSai.Equals( Vector2d.zero ) || m_TopRightSai.Equals(Vector2d.zero)) {
                m_Active = false;
                return;
            }

            GetWorldCenterOffectPoint(m_CenterOfBottomTopRightFixSai.x, m_CenterOfBottomTopRightFixSai.y);
            //m_ReiverCenterOffectPoint = m_ReiverCenterOffectPoint - m_ReiverCenterPoint;

            m_offsetLati_z = m_BottomRightFixResultSai.y - m_TopLeftFixResultSai.y;   //地图中的维度差  x
            m_offsetLon_x = m_BottomRightFixResultSai.x  - m_TopLeftFixResultSai.x;    //地图中的经度差  z

            m_XWoffsetPoint = m_BottomRightResultPoint.x - m_TopLeftResultPoint.x;//unity中的维度差   Lati
            m_ZWoffsetPoint = m_BottomRightResultPoint.z - m_TopLeftResultPoint.z;//unity中的经度差 Lon 

            m_Active = true;
        }


        public float GetRiverWidth() {
            return m_RiverWidth;
        }

        public bool linkedEachOtherFarfromSetPoint( Vector3 ShipPos ) {
            float dis = GetBilaterLength( ShipPos );
            return dis > GetRiverWidth() + 60.0f ? true : false;
        }

        public float GetBilaterLength( Vector3 ShipPos ) {
            Vector3 bottomRight = m_BottomRightPoint.position;
            bottomRight.y = ShipPos.y;

            Vector3 topRight = m_TopRightPoint.position;
            topRight.y = ShipPos.y;
            return Vector3.Distance( bottomRight, ShipPos ) + Vector3.Distance( topRight, ShipPos );
        }

        public float GetTopRightLength() {
            return m_RiverWidth;
        }

        public double ABS( double x, double y ) {
            double v = x - y;
            if (v < 0.0)
                return v * -1.0;
            return v;
        }


       public Vector2d GetCenterCoordinate(Vector2d vecBegin, Vector2d becEnd) {

            List<GeoCoordinate> geoCoordinateList = new List<GeoCoordinate>();
            GeoCoordinate g = new GeoCoordinate();
            g.setLongitude(vecBegin.x);
            g.setLatitude(vecBegin.y);
            GeoCoordinate g2 = new GeoCoordinate();
            g2.setLongitude(becEnd.x);
            g2.setLatitude(becEnd.y);
            geoCoordinateList.Add(g);
            geoCoordinateList.Add(g2);

            GeoCoordinate re = GetCenterPointFromListOfCoordinates.getCenterPoint(geoCoordinateList);
            return new Vector2d(re.getLongitude(), re.getLatitude());
        }

        public void GetWorldCenterOffectPoint(double ltx, double lgy)
        {
            if (m_offsetLon_x == 0 || m_offsetLati_z == 0)
                return ;

            double tempX = ltx - m_TopLeftFixResultSai.x;       //经线
            double tempZ = lgy - m_BottomRightFixResultSai.y;   //维线   

            double cx = (tempX * m_XWoffsetPoint / m_offsetLon_x + m_TopLeftResultPoint.x);//经度
            double cz = (tempZ * m_ZWoffsetPoint / m_offsetLati_z + m_BottomRightResultPoint.z);    //维度

            Vector3 tempPos = new Vector3((float)cx, 7.0f, (float)cz);

            willReatchPointObj.transform.SetPositionAndRotation(tempPos, Quaternion.identity);

            m_ReiverCenterOffectPoint.x = willReatchPointObj.transform.position.x ;
            m_ReiverCenterOffectPoint.y = 7.0f;
            m_ReiverCenterOffectPoint.z = willReatchPointObj.transform.position.z ;
        }


        public void GetWorldPoint( double ltx, double lgy ) {
            if (m_offsetLon_x == 0 || m_offsetLati_z == 0)
                return;
           // Vector2d tt = new Vector2d(ltx,lgy);
            //Debug.LogError("tttttt  = " + tt);
            double tempX = ltx  - m_TopLeftFixResultSai.x;       //经线
            double tempZ = lgy  - m_BottomRightFixResultSai.y;   //维线   

            double cx = (tempX * m_XWoffsetPoint / m_offsetLon_x + m_TopLeftResultPoint.x);//经度
            double cz = (tempZ * m_ZWoffsetPoint / m_offsetLati_z + m_BottomRightResultPoint.z);    //维度
           
            Vector3 tempPos = new Vector3((float)cx, 7.0f, (float)cz);

            willReatchPointObj.transform.SetPositionAndRotation(tempPos,Quaternion.identity);
            willReatchPointObj.transform.RotateAround(m_ReiverCenterPoint, Vector3.up, (float)m_riverAngle +
                GameController.DataAdjustControl.RiverAngle );
         
            m_converX = willReatchPointObj.transform.position.x ;
            m_converZ = willReatchPointObj.transform.position.z ;
        }

        private Vector3 PointRotate( Vector3 center, Vector3 p1, float angle ) {
            Vector3 tmp = new Vector3();
            float angleHude = angle * Mathf.PI / 180;/*角度变成弧度*/
            float x1 = (p1.x - center.x) * Mathf.Cos( angleHude ) + (p1.z - center.z) * Mathf.Sin( angleHude ) + center.x;
            float z1 = -(p1.x - center.x) * Mathf.Sin( angleHude ) + (p1.z - center.z) * Mathf.Cos( angleHude ) + center.z;
            tmp.x = x1;
            tmp.y = 7.0f;
            tmp.z = z1;
            return tmp;
        }
        /// <summary>
        /// 由位置点得到经纬度  
        /// </summary>
        /// <param name="curPoint"></param>
        /// <returns></returns>
        public Vector2d GetLatLon( Vector3d curPoint ) {
            //坐标偏差
            double _x_offset = (curPoint.x - m_BottomRightResultPoint.x) * m_offsetLon_x / m_XWoffsetPoint;
            double _z_offset = (curPoint.z - m_TopLeftResultPoint.z) * m_offsetLati_z / m_ZWoffsetPoint;
            double resultX = _x_offset + m_BottomRightFixResultSai.x;
            double resultZ = _z_offset + m_TopLeftFixResultSai.y;
            return new Vector2d( resultX, resultZ );
        }

        public Vector3 ChangeLatLngSpaceToUnitySceneSpace( double Posx, double Posy ) {
            if (!m_Active)
                return Vector3.zero;

            GetWorldPoint( Posx, Posy );
            return new Vector3( (float)(m_converX), 7.0f, (float)(m_converZ) );
        }

        public Vector3 ChangeLatLngSpaceToUnitySceneSpace( string Posx, string Posy ) {
            if (!m_Active)
                return Vector3.zero;

            GetWorldPoint( double.Parse( Posx ), double.Parse( Posy ) );

            return new Vector3( (float)(m_converX), 7.0f, (float)(m_converZ) );
        }

    }




}
